The DOM builder API provides a clean, declarative way to construct HTML elements from Space Lua. It is typically used to build API/widget|Widgets for rendering dynamic UI in your pages.
The full API reference is at API/dom.
Every HTML tag is available as a function on the dom table. Call it with a table of attributes and children:
dom.div {
class = "my-container",
dom.h2 { "Hello!" },
dom.p { "This is a paragraph." }
}
This creates a <div> with a class attribute, containing an <h2> and a <p>.
String keys in the table become HTML attributes. Numeric entries become children:
dom.a {
href = "https://example.com",
"Click here"
}
Markdown support: String children are automatically processed as markdown. So "**bold**" renders as bold text.
Nested elements: Other dom.* calls can be nested as children to build up a tree.
Attributes starting with on are registered as event listeners:
dom.button {
onclick = function()
editor.flashNotification("Clicked!")
end,
"Click me"
}
This is equivalent to calling addEventListener("click", fn) on the button element.
DOM elements need to be wrapped in a widget to display on a page. Use widget.html for inline or widget.htmlBlock for block-level:
-- Inline widget (rendered within text flow)
widget.html(dom.span { class = "badge", "New" })
-- Block widget (gets its own block)
widget.htmlBlock(dom.table {
dom.tr {
dom.td { "Name" },
dom.td { "Value" }
}
})
A common pattern is building HTML tables from query results:
local rows = {}
for page in query[ from index.tag "page" limit 5 ]( from index.tag "page" limit 5 ) do
table.insert(rows, dom.tr {
dom.td { "[" .. page.name .. "](" .. page.name .. ")" },
dom.td { os.date("%Y-%m-%d", page.lastModified) }
})
end
return widget.htmlBlock(dom.table {
dom.thead {
dom.tr {
dom.td { "Page" },
dom.td { "Modified" }
}
},
dom.tbody(rows)
})
Widget objects (like buttons from widgets.button) can be nested inside DOM elements:
dom.div {
"Status: ",
widgets.button("Refresh", function()
editor.invokeCommand("System: Reload")
end)
}
Under the hood, dom uses a Lua metatable so that any property access (e.g. dom.span) returns a constructor function. That function calls js.window.document.createElement(tag) and processes the spec table to set attributes, add event listeners, and append children.
See also: API/dom, API/widget, Space Lua/Widget